package com.duofan.gmall.order.config;

import com.duofan.gmall.common.utils.MyRabbitUtils;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class MyRabbitMQConfig {

    public final static String ORDER_EVENT_EXCHANGE = "order-event-exchange";
    public final static String ORDER_DELAY_QUEUE = "order.delay.queue";
    public final static String ORDER_RELEASE_ORDER_QUEUE = "order.release.order.queue";
    public final static String ORDER_CREATE_ORDER_ROUTING_KEY = "order.create.order";
    public final static String ORDER_RELEASE_ORDER_ROUTING_KEY = "order.release.order";

    public final static String ORDER_RELEASE_OTHER_ROUTING_KEY = "order.release.other.#";
    public static final String STOCK_RELEASE_STOCK_QUEUE = "stock.release.stock.queue";

    public static final String ORDER_SECKILL_ORDER_QUEUE = "order.seckill.order.queue";
    public static final String ORDER_SECKILL_ORDER_ROUTING_KEY = "order.seckill.order";

    // 订单超时时间设为30分钟
    public static final int MESSAGE_TTL = 30*60*1000;

//    @RabbitListener(queues = ORDER_RELEASE_ORDER_QUEUE)
//    public void listen(OrderEntity orderEntity, Channel channel, Message message) throws IOException {
//        System.out.println("收到过期的订单信息,准备关闭订单: " + orderEntity.getOrderSn());
//        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
//    }

    /**
     * 解决队列/交换机 不自动创建的问题
     */
    @Bean
    ApplicationRunner runner(ConnectionFactory cf) {
        return args -> cf.createConnection().close();
    }

    @Bean
    public Queue orderDelayQueue() {
        Map<String, Object> args = MyRabbitUtils.buildDeadLetterArgs(ORDER_EVENT_EXCHANGE, ORDER_RELEASE_ORDER_ROUTING_KEY, MESSAGE_TTL);
        Queue queue = new Queue(ORDER_DELAY_QUEUE, true, false, false, args);
        return queue;
    }

    @Bean
    public Queue orderReleaseOrderQueue() {
        Queue queue = new Queue(ORDER_RELEASE_ORDER_QUEUE, true, false, false);
        return queue;
    }

    @Bean
    public Queue orderSeckillOrderQueue() {
        Queue queue = new Queue(ORDER_SECKILL_ORDER_QUEUE, true, false, false);
        return queue;
    }

    @Bean
    public Exchange orderEventExchange() {
        TopicExchange exchange = new TopicExchange(ORDER_EVENT_EXCHANGE, true, false);
        return exchange;
    }

    @Bean
    public Binding orderCreateOrderBinding() {
        Binding binding = new Binding(ORDER_DELAY_QUEUE, Binding.DestinationType.QUEUE,
                ORDER_EVENT_EXCHANGE, ORDER_CREATE_ORDER_ROUTING_KEY, null);
        return binding;
    }

    @Bean
    public Binding orderReleaseOrderBinding() {
        Binding binding = new Binding(ORDER_RELEASE_ORDER_QUEUE, Binding.DestinationType.QUEUE,
                ORDER_EVENT_EXCHANGE, ORDER_RELEASE_ORDER_ROUTING_KEY, null);
        return binding;
    }

    @Bean
    public Binding orderReleaseOtherBinding() {
        Binding binding = new Binding(STOCK_RELEASE_STOCK_QUEUE, Binding.DestinationType.QUEUE,
                ORDER_EVENT_EXCHANGE, ORDER_RELEASE_OTHER_ROUTING_KEY, null);
        return binding;
    }

    @Bean
    public Binding orderSeckillOrderBinding() {
        Binding binding = new Binding(ORDER_SECKILL_ORDER_QUEUE, Binding.DestinationType.QUEUE,
                ORDER_EVENT_EXCHANGE, ORDER_SECKILL_ORDER_ROUTING_KEY, null);
        return binding;
    }
}
